// Package main 是应用程序的入口点
// 该文件负责初始化配置、连接数据库、设置路由并启动HTTP服务器
package main

import (
	"aigen-todo/internal/api"
	"aigen-todo/internal/config"
	"aigen-todo/internal/database"
	"aigen-todo/internal/utils"

	"context"
	"os"
	"os/signal"
	"syscall"
	"time"

	"go.uber.org/zap"

	// Docs
	_ "aigen-todo/swagger"
)

// @title           AI助手待办事项系统API
// @version         1.0
// @description     这是一个基于Go语言和Gin框架开发的待办事项管理系统API。
// @termsOfService  http://swagger.io/terms/

// @contact.name   API Support
// @contact.url    http://www.swagger.io/support
// @contact.email  support@swagger.io

// @license.name  Apache 2.0
// @license.url   http://www.apache.org/licenses/LICENSE-2.0.html

// @host      localhost:8080
// @BasePath  /api/v1

// @securityDefinitions.basic  BasicAuth

// @externalDocs.description  OpenAPI
// @externalDocs.url          https://swagger.io/resources/open-api/

// main 函数是应用程序的入口点
// 负责初始化配置、连接数据库、设置路由并启动HTTP服务器
func main() {
	// 初始化配置
	// LoadConfig函数从config.yaml文件加载配置
	cfg := config.LoadConfig()
	// 初始化日志
	// NewLogger函数创建一个新的zap日志记录器
	logger := utils.NewLogger(utils.LoggerConfig{
		Level:    cfg.Logger.Level,
		FilePath: cfg.Logger.FilePath,
		MaxAge:   cfg.Logger.MaxAge,
	})
	defer func() {
		// 程序退出时同步日志缓冲区
		_ = logger.Sync()
	}()
	logger.Info("Server Start ....")
	// logger.Info("Loaded config",
	// 	zap.String("port", cfg.Server.Port),
	// 	zap.String("databaseURL", cfg.Database.URL),
	// 	zap.String("jwtSecret", cfg.JWT.Secret))

	// 初始化数据库
	// Connect函数建立到PostgreSQL数据库的连接
	logger.Info("Connecting to database...")
	db, err := database.Connect(cfg.Database.URL, logger)
	if err != nil {
		logger.Fatal("Failed to connect to database", zap.Error(err))
	}

	// 处理数据库连接为nil的情况
	// 当数据库连接失败时，服务器以有限功能模式启动
	if db == nil {
		logger.Warn("Database connection is nil, starting server with limited functionality")
	} else {
		defer func() {
			// 程序退出时关闭数据库连接
			sqlDB, _ := db.DB()
			_ = sqlDB.Close()
		}()
		logger.Info("Database connected successfully")
	}

	// 设置路由
	// SetupRouter函数配置所有HTTP路由和中间件
	logger.Info("Setting up routes...")
	app := api.SetupRouter(cfg, db)

	// 启动服务器
	// 使用Fiber的Run方法启动HTTP服务器
	logger.Info("Starting server", zap.String("port", cfg.Server.Port))

	// 在goroutine中启动服务器
	// 使用goroutine异步启动服务器，避免阻塞主goroutine
	go func() {
		if err := app.Listen(cfg.Server.Port); err != nil {
			logger.Fatal("Server error", zap.Error(err))
		}
	}()
	logger.Info("Server started successfully")

	// 等待中断信号以优雅地关闭服务器
	// 监听系统中断信号（如Ctrl+C）以实现优雅关闭
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit
	logger.Info("Shutting down server...")

	// 创建一个带有超时的上下文用于关闭
	// 设置5秒超时以确保服务器有足够时间完成正在进行的请求
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	// 尝试优雅地关闭服务器
	// Shutdown方法会等待所有正在进行的请求完成后再关闭服务器
	if err := app.ShutdownWithContext(ctx); err != nil {
		logger.Fatal("Server forced to shutdown", zap.Error(err))
	}

	logger.Info("Server exited")
}
